﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ZOVNP.WinView.Workplaces.Seller
{
    internal class CustomEditorDataGridViewTextBoxCell : DataGridViewTextBoxCell
    {
        public override Type EditType
        {
            get
            {
                return typeof(DataGridViewDropDownListComboBoxEditingControl);
            }
        }
    }

    /// <summary> Редактор ссылочной ячейки DataGridView с возможностью ввода значений </summary>
    public class DataGridViewDropDownComboBoxEditingControl : DataGridViewComboBoxEditingControl
    {
        /// <summary> Конструктор по-умолчанию </summary>
        public DataGridViewDropDownComboBoxEditingControl()
            : base()
        {
            base.DropDownStyle = ComboBoxStyle.DropDown;
        }
        /// <summary> Обработчик закрытия списка значений </summary>
        /// <param name="e"> параметры события </param>
        protected override void OnDropDownClosed(EventArgs e)
        {
            base.OnDropDownClosed(e);
            if (base.EditingControlValueChanged)
                SendKeys.Send("{Enter}");
        }
        /// <summary> Обработчик изменения стиля </summary>
        /// <param name="e"> параметры события </param>
        ///<remarks> Какая-то гнида меняет его стиль </remarks>
        protected override void OnDropDownStyleChanged(EventArgs e)
        {
            base.OnDropDownStyleChanged(e);
            if (base.DropDownStyle != ComboBoxStyle.DropDown)
                base.DropDownStyle = ComboBoxStyle.DropDown;
        }
        /// <summary> Обработчик изменения вводимого значения </summary>
        /// <param name="e"> параметры события </param>
        protected override void OnTextChanged(EventArgs e)
        {
            this.NotifyDataGridViewOfValueChange(true);
            base.OnTextChanged(e);
        }
        /// <summary> Обработчик определения клавиш ввода </summary>
        /// <param name="keyData"> ввод</param>
        /// <param name="dataGridViewWantsInputKey"> флаг </param>
        /// <returns> true если клавиша обрабатывается редактором, в противном случае - false </returns>
        public override bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
        {
            switch (keyData & Keys.KeyCode)
            {
                case Keys.Delete:
                case Keys.Enter:
                case Keys.Left:
                case Keys.Right:
                case Keys.End:
                case Keys.Home:
                    return (true); // "наши" клавиши
                default:
                    return (base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey));
            }
        }
        /// <summary> Уведомить грид об изменении значения </summary>
        /// <param name="dirty"> флаг изменения значения </param>
        protected virtual void NotifyDataGridViewOfValueChange(bool dirty)
        {
            base.EditingControlValueChanged = dirty;
            base.EditingControlDataGridView.NotifyCurrentCellDirty(dirty);
        }
    }

    /// <summary> Редактор ссылочной ячейки DataGridView с возможностью ввода значений только из списка </summary>
    public class DataGridViewDropDownListComboBoxEditingControl : DataGridViewDropDownComboBoxEditingControl
    {
        /// <summary> Конструктор по-умолчанию </summary>
        public DataGridViewDropDownListComboBoxEditingControl()
            : base() { }

        /// <summary> Обработчик нажатия клавиши </summary>
        /// <param name="e"> параметры события </param>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (!Char.IsControl(e.KeyChar))
            {
                int start = base.SelectionStart;
                string find = (base.SelectionLength > 0) ? base.Text.Remove(start, base.SelectionLength) : base.Text;

                if (start < find.Length)
                    find = find.Insert(start, e.KeyChar.ToString());
                else
                    find += e.KeyChar.ToString();

                int index = base.FindString(find);
                if (index < 0)
                    // если не нашли, то игнорируем ввод
                    e.Handled = true;
            }
            base.OnKeyPress(e);
        }
    }
}
